/*
	This file is part of AVRCppLib.

    AVRCppLib is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    AVRCppLib is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with AVRCppLib.  If not, see <http://www.gnu.org/licenses/>.

    Copyright (C) Maxime Lemonnier 2007-2011
 */

#ifndef SPIHardware_H_
#define SPIHardware_H_

#include "../../Utils/CppExtensions.h"
#include "../../Utils/BitManipulation.h"
#include "../../CallbackServers/CallbackConnector.h"
#include "Compatibility/SPIHardwareCompatibilityInterface.h"

namespace Coms
{

namespace SPI
{

namespace Prescalers
{

enum Prescaler
{
	DIV_4 = 0x00,
	DIV_16 = 0x01,
	DIV_64 = 0x02,
	DIV_128 = 0x03
};

}

using Prescalers::Prescaler;

class SPIHardware : public CallbackConnector
{

public:

	static SPIHardware * getSPIHardware(size_t number);

	virtual ~SPIHardware();

	inline void enable() FORCE_INLINE;

	inline void disable() FORCE_INLINE;

	inline void enableInterrupts() FORCE_INLINE;

	inline void disableInterrupts() FORCE_INLINE;

	inline bool readInterruptFlag() FORCE_INLINE;

	inline void clearInterruptFlag() FORCE_INLINE;

	inline void transmitLSBFirst() FORCE_INLINE;

	inline void transmitMSBFirst() FORCE_INLINE;

	inline void setMaster() FORCE_INLINE;

	inline void setSlave() FORCE_INLINE;

	inline void setSPIPinsDirections(DataDirection slaveSelectPinDirection = INPUT, DataDirection sckPinDirection = OUTPUT, DataDirection mosiPinDirection = OUTPUT, DataDirection misoPinDirection = OUTPUT) FORCE_INLINE;

	inline void setSCKHighWhenIdle() FORCE_INLINE;

	inline void setSCKLowWhenIdle() FORCE_INLINE;

	inline void sampleDataOnSCKLeadingEdge() FORCE_INLINE;

	inline void sampleDataOnSCKTrailingEdge() FORCE_INLINE;

	inline void setPrescaler(Prescaler prescaler, bool doubleBitRate) FORCE_INLINE;

	inline bool checkWriteCollision() FORCE_INLINE;

	inline uint8_t readByte() FORCE_INLINE;

	inline void writeByte(uint8_t byte) FORCE_INLINE;

protected:

	SPIHardware(uint8_t callbackVectorNumber, IOAddress spcr, IOAddress spsr, IOAddress spdr, IOAddress spiDDR, uint8_t ssPinNumber, uint8_t sckPinNumber, uint8_t mosiPinNumber, uint8_t misoPinNumber);

	IOAddress spcr;
	IOAddress spsr;
	IOAddress spdr;

	IOAddress spiDDR;
	uint8_t ssPinNumber;
	uint8_t sckPinNumber;
	uint8_t mosiPinNumber;
	uint8_t misoPinNumber;

};

#include "SPIHardware-definitions.h"

}

}

#endif /* SPIHardware_H_ */
